/*
	klib_message_passing.c

	contains functionality for IPC message passing

	Author: Aidan Goddard 4/10/13
*/

#include"../kernel/headers/message_handling.h"
#include"headers/klib_message_passing.h"

MSG_CHANNEL	__KLIB__MSGAllocateChannel(char *magic_string, uint32_t magic_int)
{
	return AllocateChannel(magic_string, magic_int);
}

uint32_t	__KLIB__MSGDeallocateChannel(MSG_CHANNEL channel)
{
	uint32_t to_return = DeallocateChannel(channel);

	if(to_return == 1)
	{
		return MSG_INVALID_CHANNEL;
	}
	else if(to_return == 2)
	{
		return MSG_NOT_SERVER;
	}
	else
	{
		return MSG_SUCCESS;
	}
}

MSG_CHANNEL __KLIB__MSGFindChannel(char *magic_string, uint32_t magic_int)
{
	return FindChannel(magic_string, magic_int);
}

uint32_t	__KLIB__MSGClientBindChannel(MSG_CHANNEL channel, uint64_t PID)
{
	uint32_t to_return = ClientBindChannel(PID, channel);

	if(to_return == 1)
	{
		return MSG_INVALID_CHANNEL;
	}
	else if(to_return == 2)
	{
		return MSG_CHANNEL_BOUND;
	}
	else
	{
		return MSG_SUCCESS;
	}
}

uint32_t	__KLIB__MSGServerRead(MSG_CHANNEL channel, uint8_t *buffer)
{
	uint32_t to_return = ServerRead(channel, buffer);

	if(to_return == 1)
	{
		return MSG_INVALID_CHANNEL;
	}
	else if(to_return == 2)
	{
		return MSG_READ_CONT;
	}
	else if(to_return == 3)
	{
		return MSG_PREMATURE_WAKE;
	}
	else if(to_return == 4)
	{
		return MSG_WRITE_CONT;
	}
	else if(to_return == 5)
	{
		return MSG_NOT_SERVER;
	}
	else
	{
		return MSG_SUCCESS;
	}
}

uint32_t	__KLIB__MSGServerPeek(MSG_CHANNEL channel)
{
	uint32_t to_return = ServerPeek(channel);

	if(to_return == 1)
	{
		return MSG_NO_MSG_EXIST;
	}
	else if(to_return == 2)
	{
		return MSG_INVALID_CHANNEL;
	}
	else if(to_return == 3)
	{
		return MSG_NOT_SERVER;
	}
	else
	{
		return MSG_MSG_EXIST;
	}
}

uint32_t	__KLIB__MSGClientRead(MSG_CHANNEL channel, uint8_t *buffer, uint64_t PID)
{
	uint32_t to_return = ClientRead(channel, buffer, PID);

	if(to_return == 1)
	{
		return MSG_INVALID_CHANNEL;
	}
	else if(to_return == 2)
	{
		return MSG_READ_CONT;
	}
	else if(to_return == 3)
	{
		return MSG_PREMATURE_WAKE;
	}
	else if(to_return == 4)
	{
		return MSG_WRITE_CONT;
	}
	else if(to_return == 5)
	{
		return MSG_NOT_CLIENT;
	}
	else
	{
		return MSG_SUCCESS;
	}
}

uint32_t	__KLIB__MSGClientPeek(MSG_CHANNEL channel, uint64_t PID)
{
	uint32_t to_return = ClientPeek(channel, PID);

	if(to_return == 1)
	{
		return MSG_NO_MSG_EXIST;
	}
	else if(to_return == 2)
	{
		return MSG_INVALID_CHANNEL;
	}
	else if(to_return == 3)
	{
		return MSG_NOT_CLIENT;
	}
	else
	{
		return MSG_MSG_EXIST;
	}
}

// message send functions
// returns 0 on success, 1 if channel is not valid, 2 if the calling PID is not the server, 3 if the buffer is full,
// 4 if there is already a thread waiting on a sync write, 5 if the thread was woken by something else
uint32_t	__KLIB__MSGServerSendSync(MSG_CHANNEL channel, uint8_t *buffer)
{
	uint32_t to_return = ServerSendSync(channel, buffer);

	if(to_return == 1)
	{
		return MSG_INVALID_CHANNEL;
	}
	else if(to_return == 2)
	{
		return MSG_NOT_SERVER;
	}
	else if(to_return == 3)
	{
		return MSG_BUFFER_FULL;
	}
	else if(to_return == 4)
	{
		return MSG_WRITE_CONT;
	}
	else if(to_return == 5)
	{
		return MSG_PREMATURE_WAKE;
	}
	else
	{
		return MSG_SUCCESS;
	}
}

// function for the server to send an async message to the client
// returns 0 on success, 1 if channel is not valid, 2 if calling PID is not the server, 3 if the client's buffer is full.
uint32_t 	__KLIB__MSGServerSendAsync(MSG_CHANNEL channel, uint8_t *buffer)
{
	uint32_t to_return = ServerSendAsync(channel, buffer);

	if(to_return == 1)
	{
		return MSG_INVALID_CHANNEL;
	}
	else if(to_return == 2)
	{
		return MSG_NOT_SERVER;
	}
	else if(to_return == 3)
	{
		return MSG_BUFFER_FULL;
	}
	else
	{
		return MSG_SUCCESS;
	}
}


// message send functions
// returns 0 on success, 1 if channel is not valid, 2 if the calling PID is not the client, 3 if the buffer is full,
// 4 if there is already a thread waiting on a sync write, 5 if the thread was woken by something else
uint32_t 	__KLIB__MSGClientSendSync(MSG_CHANNEL channel, uint8_t *buffer, uint64_t PID)
{
	uint32_t to_return = ClientSendSync(channel, buffer, PID);

	if(to_return == 1)
	{
		return MSG_INVALID_CHANNEL;
	}
	else if(to_return == 2)
	{
		return MSG_NOT_CLIENT;
	}
	else if(to_return == 3)
	{
		return MSG_BUFFER_FULL;
	}
	else if(to_return == 4)
	{
		return MSG_WRITE_CONT;
	}
	else if(to_return == 5)
	{
		return MSG_PREMATURE_WAKE;
	}
	else
	{
		return MSG_SUCCESS;
	}
}


// function for the client to send an async message to the server
// returns 0 on success, 1 if channel is not valid, 2 if calling PID is not the client, 3 if the server's buffer is full.
uint32_t 	__KLIB__MSGClientSendAsync(MSG_CHANNEL channel, uint8_t *buffer, uint64_t PID)
{
	uint32_t to_return = ClientSendAsync(channel, buffer, PID);

	if(to_return == 1)
	{
		return MSG_INVALID_CHANNEL;
	}
	else if(to_return == 2)
	{
		return MSG_NOT_CLIENT;
	}
	else if(to_return == 3)
	{
		return MSG_BUFFER_FULL;
	}
	else
	{
		return MSG_SUCCESS;
	}
}

uint32_t	__KLIB__MSGGetClientPendingMessages(MSG_CHANNEL channel)
{
	return GetClientPendingMessages(channel);
}

uint32_t	__KLIB__MSGGetServerPendingMessages(MSG_CHANNEL channel)
{
	return GetServerPendingMessages(channel);
}
















